# -*- coding: utf-8 -*-
from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.response import Response

from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.system.models import Role, Menu, Dept, RoleMenuPermission, RoleMenuButtonPermission
from dvadmin.utils.json_response import DetailResponse, SuccessResponse
from dvadmin.utils.viewset import CustomModelViewSet


class RoleSerializer(CustomModelSerializer):
    """
    角色-序列化器
    """

    class Meta:
        model = Role
        fields = "__all__"
        read_only_fields = ["id"]


class RoleCreateSerializer(CustomModelSerializer):
    """
    角色新增-序列化器
    """

    class Meta:
        model = Role
        fields = "__all__"
        read_only_fields = ["id"]


class RoleUpdateSerializer(CustomModelSerializer):
    """
    角色修改-序列化器
    """

    class Meta:
        model = Role
        fields = "__all__"
        read_only_fields = ["id"]


class RoleDataScopeSerializer(CustomModelSerializer):
    """
    角色数据权限-序列化器
    """
    deptIds = serializers.ListField(required=False, help_text="部门id集合")

    class Meta:
        model = Role
        fields = ["id",  "deptIds"]
        read_only_fields = ["id"]


class RoleViewSet(CustomModelViewSet):
    """
    角色管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    create_serializer_class = RoleCreateSerializer
    update_serializer_class = RoleUpdateSerializer
    filter_fields = ["name", "key", "status"]
    search_fields = ["name", "key"]

    def create(self, request, *args, **kwargs):
        """
        重写create方法，新增角色时，需要同步新增角色菜单权限
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        menu_ids = request.data.get('menuIds', [])
        instance = serializer.save()
        if menu_ids:
            menu_obj_list = Menu.objects.filter(id__in=menu_ids)
            for menu in menu_obj_list:
                RoleMenuPermission.objects.create(role=instance, menu=menu)
        return DetailResponse(data=serializer.data, msg="新增成功")

    def update(self, request, *args, **kwargs):
        """
        重写update方法，修改角色时，需要同步修改角色菜单权限
        """
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        menu_ids = request.data.get('menuIds', [])
        instance = serializer.save()
        RoleMenuPermission.objects.filter(role=instance).delete()
        if menu_ids:
            menu_obj_list = Menu.objects.filter(id__in=menu_ids)
            for menu in menu_obj_list:
                RoleMenuPermission.objects.create(role=instance, menu=menu)
        return DetailResponse(data=serializer.data, msg="修改成功")

    @action(methods=["PUT"], detail=True, serializer_class=RoleDataScopeSerializer,
            permission_classes=[])
    def dataScope(self, request, pk=None):
        """
        修改数据权限
        """
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        dept_ids = request.data.get('deptIds', [])
        instance = serializer.save()
        RoleMenuButtonPermission.objects.filter(role=instance).delete()
        if dept_ids:
            dept_obj_list = Dept.objects.filter(id__in=dept_ids)
            for dept in dept_obj_list:
                RoleMenuButtonPermission.objects.create(role=instance, menu_button=dept)
        return DetailResponse(data=serializer.data, msg="修改成功")

    @action(methods=["PUT"], detail=True, permission_classes=[])
    def changeStatus(self, request, pk=None):
        """
        修改状态
        """
        instance = self.get_object()
        instance.status = request.data.get("status", True)
        instance.save()
        return SuccessResponse(data=instance.status, msg="修改成功")

    @action(methods=["GET"], detail=False, permission_classes=[])
    def treeselect(self, request, *args, **kwargs):
        """
        获取角色树
        """
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        data = []
        for item in serializer.data:
            data.append(
                {
                    "id": item.get("id"),
                    "label": item.get("name"),
                }
            )
        return Response(data)

    @action(methods=["GET"], detail=True, permission_classes=[])
    def roleMenuTreeselect(self, request, pk=None, *args, **kwargs):
        """
        获取角色拥有的菜单权限
        """
        try:
            instance = self.get_object()
            menu_ids = RoleMenuPermission.objects.filter(role=instance).values_list('menu_id', flat=True)
            menus = Menu.objects.filter(status=True).order_by('sort')
            serializer = MenuTreeSerializer(menus, many=True)
            return Response({"menus": serializer.data, "checkedKeys": list(menu_ids)})
        except Exception as e:
            return Response({"menus": [], "checkedKeys": []})

    @action(methods=["GET"], detail=True, permission_classes=[])
    def deptTreeSelect(self, request, pk=None, *args, **kwargs):
        """
        获取角色拥有的部门权限
        """
        try:
            instance = self.get_object()
            dept_ids = RoleMenuButtonPermission.objects.filter(role=instance).values_list('menu_button_id', flat=True)
            depts = Dept.objects.filter(status=True).order_by('sort')
            serializer = DeptTreeSerializer(depts, many=True)
            return Response({"depts": serializer.data, "checkedKeys": list(dept_ids)})
        except Exception as e:
            return Response({"depts": [], "checkedKeys": []})


class MenuTreeSerializer(CustomModelSerializer):
    """
    菜单管理-树结构
    """
    children = serializers.SerializerMethodField()

    def get_children(self, obj: Menu):
        data = []
        instance = Menu.objects.filter(parent_id=obj.id, status=True).order_by('sort')
        if instance:
            serializer = MenuTreeSerializer(instance=instance, many=True)
            data = serializer.data
        return data

    class Meta:
        model = Menu
        fields = ["id", "name", "children"]


class DeptTreeSerializer(CustomModelSerializer):
    """
    部门管理-树结构
    """
    children = serializers.SerializerMethodField()

    def get_children(self, obj: Dept):
        data = []
        instance = Dept.objects.filter(parent_id=obj.id, status=True).order_by('sort')
        if instance:
            serializer = DeptTreeSerializer(instance=instance, many=True)
            data = serializer.data
        return data

    class Meta:
        model = Dept
        fields = ["id", "name", "children"]
